Björn Augustsson contributes support for Humminbird waypoint files (.hwr).
authoroliskoli <oliskoli>
Thu, 14 Aug 2008 07:11:50 +0000 (07:11 +0000)
committeroliskoli <oliskoli>
Thu, 14 Aug 2008 07:11:50 +0000 (07:11 +0000)
Makefile.in
humminbird.c [new file with mode: 0644]
vecs.c

index 27bdd78a5dd4f8ec39ff40a60596554c330a4ae2..90bfb9752cce91bc393951923d04c0ff1a71eda2 100644 (file)
@@ -59,7 +59,7 @@ ALL_FMTS=$(MINIMAL_FMTS) gtm.o gpsutil.o pcx.o cetus.o copilot.o \
        wbt-200.o stmsdf.o gtrnctr.o dmtlog.o raymarine.o alan.o vitovtt.o \
        ggv_log.o g7towin.o garmin_gpi.o lmx.o random.o xol.o dg-100.o \
        navilink.o mtk_logger.o ik3d.o osm.o destinator.o exif.o vidaone.o \
-       igo8.o gopal.o
+       igo8.o gopal.o humminbird.o
 
 FMTS=@FMTS@
 
@@ -559,6 +559,8 @@ html.o: html.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \
   jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
   jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h jeeps/gpsinput.h jeeps/gpsproj.h
+humminbird.o: humminbird.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
+  zlib/zconf.h gbfile.h cet.h cet_util.h inifile.h
 igc.o: igc.c defs.h config.h queue.h gbtypes.h zlib/zlib.h zlib/zconf.h \
   gbfile.h cet.h cet_util.h inifile.h
 ignrando.o: ignrando.c defs.h config.h queue.h gbtypes.h zlib/zlib.h \
diff --git a/humminbird.c b/humminbird.c
new file mode 100644 (file)
index 0000000..8a96ac7
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+    Copyright (C) 2008  Björn Augustsson, oggust@gmail.com
+    Copyright (C) 2008  Olaf Klein, o.b.klein@gpsbabel.org
+    Copyright (C) 2005  Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include <ctype.h>
+
+#define MYNAME "humminbird"
+
+#define EAST_SCALE       20038297.0 /* this is i1924_equ_axis*M_PI */
+#define i1924_equ_axis   6378388.0
+#define i1924_polar_axis 6356911.946
+
+static
+arglist_t humminbird_args[] = {
+// {"foo", &fooopt, "The text of the foo option in help", 
+//   "default", ARGYTPE_STRING, ARG_NOMINMAX} , 
+       ARG_TERMINATOR
+};
+
+/* The hwr data format is records-based, and the records are 36 bytes long. */
+
+typedef struct humminbird_waypt_s {
+        gbuint32 signature;    /* Just for error checking(?) */
+        gbuint16 num;          /* Always ascending in the file. */
+        gbuint16 zero;         /* Always seems to be zero. */
+        gbuint8  status;       /* Always seems to be 1 */
+        gbuint8  icon;         /* See below */
+        gbuint16 depth;        /* Water depth. These are fishfinders. In centimeters */
+        gbuint32 time;         /* This is a time_t. In UTC */
+        gbint32  east;
+        gbint32  north;
+        char     name[12];
+} humminbird_waypt_t;
+
+# if 0
+static const char* humminbird_icons[] = {
+       "Normal",       /*  0 */
+       "House",        /*  1 */
+       "Red cross",    /*  2 */
+       "Fish",         /*  3 */
+       "Duck",         /*  4 */
+       "Anchor",       /*  5 */
+       "Buoy",         /*  6 */
+       "Airport",      /*  7 */
+       "Camping",      /*  8 */
+       "Danger",       /*  9 */
+       "Petrol",       /* 10 */
+       "Rock",         /* 11 */
+       "Weed",         /* 12 */
+       "Wreck",        /* 13 */
+       "Phone",        /* 14 */
+       "Coffee",       /* 15 */
+       "Beer",         /* 16 */
+       "Mooring",      /* 17 */
+       "Pier",         /* 18 */
+       "Slip",         /* 19 */
+       "Ramp",         /* 20 */
+       "Circle",       /* 21 */
+       "Diamond",      /* 22 */
+       "Flag",         /* 23 */
+       "Pattern",      /* 24 */
+       "Shower",       /* 25 */
+       "Water tap",    /* 26 */
+       "Tree",         /* 27 */
+       "Recording",    /* 28 */
+       "Snapshot"      /* 29 */
+};
+#endif
+
+static gbfile* fin;
+
+# if 0
+/* Takes a latitude in degrees,
+ * returns a latitude in degrees. */
+static double
+geodetic_to_geocentric_hwr(const double gd_lat) {
+       const double cos_ae = 0.9966349016452;
+        const double cos2_ae = cos_ae * cos_ae;
+
+        const double gdr = gd_lat *M_PI / 180.0;
+
+        return atan(cos2_ae * tan(gdr)) * 180.0/M_PI;
+}
+#endif
+
+/* Takes a latitude in degrees,
+ * returns a latitude in degrees. */
+static double
+geocentric_to_geodetic_hwr(const double gc_lat) {
+//        const double cos_ae = i1924_polar_axis/i1924_equ_axis;
+       const double cos_ae = 0.9966349016452;
+
+       const double cos2_ae = cos_ae * cos_ae;
+
+       const double gcr = gc_lat *M_PI / 180.0;
+
+       return atan( tan(gcr)/cos2_ae ) * 180.0/M_PI;
+}
+
+/* Takes a projected "north" value, returns latitude in degrees. */
+static double
+gudermannian_i1924(const double x) {
+       const double norm_x = x/i1924_equ_axis;
+
+        return atan(sinh(norm_x)) * 180.0/M_PI;
+}
+
+#if 0
+/* Takes latitude in degrees, returns projected "north" value. */
+static double
+inverse_gudermannian_i1924(const double x) {
+        const double x_r = x/180.0 * M_PI;
+        const double guder = log(tan(M_PI/4.0 + x_r/2.0));
+
+        return guder * i1924_equ_axis;
+}
+#endif 
+
+/*******************************************************************************
+* %%%        global callbacks called by gpsbabel main process              %%% *
+*******************************************************************************/
+
+static void
+humminbird_rd_init(const char *fname)
+{
+       fin = gbfopen(fname, "r", MYNAME);
+}
+
+static void 
+humminbird_rd_deinit(void)
+{
+       gbfclose(fin);
+}
+
+static void
+humminbird_read(void)
+{
+       
+       while(! gbfeof(fin)) {
+               humminbird_waypt_t w;
+               double guder;
+               int bytes;
+               waypoint *wpt;
+
+               bytes = gbfread(&w, 1, sizeof(humminbird_waypt_t), fin);
+               if(bytes == 0) break;
+
+               is_fatal((bytes != sizeof(humminbird_waypt_t)),
+                        MYNAME ": Unexpected end of file (%d)!",
+                        (int)sizeof(humminbird_waypt_t) - bytes);
+
+               /* Fix endianness - these are now BE */
+               w.signature = be_read32(&w.signature);
+               w.num       = be_read16(&w.num);
+               w.zero      = be_read16(&w.zero);
+               w.depth     = be_read16(&w.depth);
+               w.time      = be_read32(&w.time);
+               w.north     = be_read32(&w.north);
+               w.east      = be_read32(&w.east);
+
+               is_fatal(( w.signature != 0x02020024L ),
+                        MYNAME ": Invalid record header (no or unknown humminbird file)!");
+               
+               /* All right! Copy the data to the gpsbabel struct... */
+               
+               wpt = waypt_new();
+
+               wpt->shortname = xstrndup(w.name, sizeof(w.name));
+               wpt->creation_time = w.time;
+
+               guder = gudermannian_i1924(w.north);
+               wpt->latitude = geocentric_to_geodetic_hwr(guder);
+               wpt->longitude = (double)w.east / EAST_SCALE * 180.0;
+
+               wpt->altitude  = 0.0; /* It's from a fishfinder... */
+               
+               if(w.depth != 0)
+                       WAYPT_SET(wpt,depth,(double)w.depth / 100.0);
+
+               waypt_add(wpt);
+       }
+}
+
+#if 0
+static void
+humminbird_wr_init(const char *fname)
+{
+//     fout = gbfopen(fname, "w", MYNAME);
+}
+
+static void
+humminbird_wr_deinit(void)
+{
+//     gbfclose(fout);
+}
+
+static void
+humminbird_write(void)
+{
+}
+#endif
+
+/**************************************************************************/
+/*       capabilities below means: we can only read  waypoints            */
+/**************************************************************************/
+
+ff_vecs_t humminbird_vecs = {
+       ff_type_file,
+       { 
+               ff_cap_read,    /* waypoints */
+               ff_cap_none,    /* tracks */
+               ff_cap_none     /* routes */
+       },
+       humminbird_rd_init,     
+       NULL,   /* humminbird_wr_init, */
+       humminbird_rd_deinit,   
+       NULL,   /* humminbird_wr_deinit, */
+       humminbird_read,
+       NULL,   /* humminbird_write, */
+       NULL,   /* humminbird_exit, */
+       humminbird_args,
+       CET_CHARSET_ASCII, 0
+};
+
+/**************************************************************************/
diff --git a/vecs.c b/vecs.c
index eb09ee783a7dc189255a59ef14fb4eefd0027ede..29e38f8ae232a331655a57cc525f70ed6ffc132c 100644 (file)
--- a/vecs.c
+++ b/vecs.c
@@ -141,6 +141,7 @@ extern ff_vecs_t destinator_itn_vecs;
 extern ff_vecs_t exif_vecs;
 extern ff_vecs_t vidaone_vecs;
 extern ff_vecs_t gopal_vecs;
+extern ff_vecs_t humminbird_vecs;
 
 static
 vecs_t vec_list[] = {
@@ -802,6 +803,12 @@ vecs_t vec_list[] = {
                 "GoPal GPS track log (.trk)",
                "trk"
         },
+       {
+               &humminbird_vecs,
+               "humminbird",
+               "Humminbird waypoints (.hwr)",
+               "hwr"
+        },
 #endif // MAXIMAL_ENABLED
        {
                NULL,